Execute os comandos presentes no arquivo setup.R,
presente na pasta scripts, para instalar os pacotes que
serão necessários durante o minicurso. O tempo de execução do comando
vai variar dependendo da instalação do R em seu computador
e da sua conexão à internet. O script vai localizar quais pacotes já
estão instalados em sua máquina e irá baixar apenas aqueles que
estiverem faltando.
Este é um documento R Markdown. Markdown é uma linguagem de markup para formatar textos para formatos como HTML, PDF e Word, dentre outros. Para mais detalhes sobre o formato, visite o link http://rmarkdown.rstudio.com.
Ao clicar no botão Knit acima ou utilizar o atalho
Ctrl+Shift+K, será gerado um documento que juntará
texto regular, código do R e os respectivos
outputs destes códigos, unindo tudo em um mesmo documento.
A criação de mapas no R pode ser um pouco lenta. Por
isso, na linha 17 deste arquivo está uma opção identificada como
cache = TRUE. Com isso, apenas trechos de códigos novos ou
alterados serão executados a cada compilação do documento. Caso haja
algum problema com a atualização dos resultados no arquivo html gerado,
apague as pastas 02_estatisticas_brasileiras_cache e
02_estatisticas_brasileiras_files para que um novo arquivo
seja compilado completamente a partir do zero.
Como o pacote giscoR não apresenta dados detalhados o
suficiente para todos os países do mundo, pois é focado na União
Europeia, precisamos procurar uma alternativa para plotar dados do
Brasil. Vamos usar o pacote geobr para isso.
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.3 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.4 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.0
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
theme_set(theme_void())
library(geobr)
## Loading required namespace: sf
A função read_municipality importa os dados dos mapas em
nível municipal. Ou seja, com ela obtemos o mapa do Brasil com os
limites entre cada cidade:
cidades <- read_municipality(year = 2020, showProgress = FALSE)
## Using year 2020
Vamos conferir o conteúdo do objeto cidades:
head(cidades)
## Simple feature collection with 6 features and 7 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -63.61801 ymin: -13.6937 xmax: -60.33317 ymax: -9.66916
## Geodetic CRS: SIRGAS 2000
## code_muni name_muni code_state abbrev_state name_state
## 1 1100015 Alta Floresta D'oeste 11 RO Rondônia
## 2 1100023 Ariquemes 11 RO Rondônia
## 3 1100031 Cabixi 11 RO Rondônia
## 4 1100049 Cacoal 11 RO Rondônia
## 5 1100056 Cerejeiras 11 RO Rondônia
## 6 1100064 Colorado Do Oeste 11 RO Rondônia
## code_region name_region geom
## 1 1 Norte MULTIPOLYGON (((-62.19465 -...
## 2 1 Norte MULTIPOLYGON (((-62.53648 -...
## 3 1 Norte MULTIPOLYGON (((-60.37119 -...
## 4 1 Norte MULTIPOLYGON (((-61.0008 -1...
## 5 1 Norte MULTIPOLYGON (((-61.49976 -...
## 6 1 Norte MULTIPOLYGON (((-60.50475 -...
São diversas informações:
code_muni: código do município no IBGEname_muni: nome do municípiocode_state: código da UF do município no IBGEabbrev_state: sigla da UFname_state: nome da UFcode_region: código da região do paísname_region: nome da região do paísgeom: mapa para cada municipioA lógica para plotar o mapa do Brasil é a mesma que utilizamos para plotar o mapa múndi:
ggplot(cidades) +
geom_sf(fill = "white")
Mas se quisermos podemos plotar estatísticas em cima desde mapa. Em
particular, vamos ler o conteúdo do arquivo brasil.csv:
brasil <- read_csv(file = "dados/brasil.csv")
## Rows: 5570 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): municipio, uf
## dbl (4): codigo_ibge, area, populacao, densidade
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Estas são as suas primeiras linhas:
head(brasil)
## # A tibble: 6 × 6
## codigo_ibge municipio uf area populacao densidade
## <dbl> <chr> <chr> <dbl> <dbl> <dbl>
## 1 3550308 São Paulo São Paulo 1521. 11451245 7528.
## 2 3304557 Rio de Janeiro Rio de Janeiro 1200. 6211423 5175.
## 3 5300108 Brasília Distrito Federal 5761. 2817068 489.
## 4 2304400 Fortaleza Ceará 312. 2428678 7775.
## 5 2927408 Salvador Bahia 693. 2418005 3487.
## 6 3106200 Belo Horizonte Minas Gerais 331. 2315560 6988.
Cada coluna apresenta uma informação diferente:
codigo_ibge: código do município no IBGEmunicipio: nome do municípiouf: nome da UFarea: área do município (km^2)populacao: quantidade de habitantes do municípiodensidade: densidade populacional do município
(habitantes/km^2)Queremos colorir o mapa do Brasil de acordo com a densidade
populacional de cada município. Para isso, precisamos juntar em um mesmo
objeto os mapas e as informações que queremos plotar. Como as cidades
não estão na mesma ordem nos objetos municipios e
brasil, vamos utilizar a função left_join para
nos auxiliar nisso. Ela é uma função que permite relacionar dois
conjuntos de dados a partir de uma chave comum a eles.
Tome por exemplo os conjuntos de dados abaixo. Ambos possuem as mesmas pessoas, mas com informações diferentes sobre elas.
telefones <- data.frame(nome = c("João", "Maria", "Pedro", "Roberta"),
telefone = c("84 99999-1000", "84 99999-2000", "84 99999-3000", "84 99999-4000"))
emails <- data.frame(nome = c("Maria", "Roberta", "João", "Pedro"),
email = c("m@ufrn.br", "roberta@gmail.com", "joao@ufrn.br", "pedro@hotmail.com"))
telefones
## nome telefone
## 1 João 84 99999-1000
## 2 Maria 84 99999-2000
## 3 Pedro 84 99999-3000
## 4 Roberta 84 99999-4000
emails
## nome email
## 1 Maria m@ufrn.br
## 2 Roberta roberta@gmail.com
## 3 João joao@ufrn.br
## 4 Pedro pedro@hotmail.com
Note que nome é uma chave comum a ambos conjuntos de
dados. Embora a ordem dos nomes não seja a mesma, a função
left_join consegue relacionar ambos os conjuntos de dados e
identificar quais informações devem ser atribuídas a cada pessoa:
telefones |>
left_join(emails, by = "nome")
## nome telefone email
## 1 João 84 99999-1000 joao@ufrn.br
## 2 Maria 84 99999-2000 m@ufrn.br
## 3 Pedro 84 99999-3000 pedro@hotmail.com
## 4 Roberta 84 99999-4000 roberta@gmail.com
Iremos utilizar esta mesma lógica para unir os conjuntos
cidades e brasil, para colocarmos as
informações de ambos bancos de dados em um mesmo objeto. Neste caso,
iremos sobrescrever o conteúdo de cidades. Como chave,
utilizaremos o código do IBGE, para evitar problemas com acentuação
(Mossoró vs Mossoro) ou grafia (Assu vs Açu) dos nomes dos
municípios.
O resultado é o seguinte:
cidades <-
cidades |>
rename(codigo_ibge = code_muni) |>
left_join(brasil, by = "codigo_ibge")
head(cidades)
## Simple feature collection with 6 features and 12 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -63.61801 ymin: -13.6937 xmax: -60.33317 ymax: -9.66916
## Geodetic CRS: SIRGAS 2000
## codigo_ibge name_muni code_state abbrev_state name_state
## 1 1100015 Alta Floresta D'oeste 11 RO Rondônia
## 2 1100023 Ariquemes 11 RO Rondônia
## 3 1100031 Cabixi 11 RO Rondônia
## 4 1100049 Cacoal 11 RO Rondônia
## 5 1100056 Cerejeiras 11 RO Rondônia
## 6 1100064 Colorado Do Oeste 11 RO Rondônia
## code_region name_region municipio uf area populacao
## 1 1 Norte Alta Floresta d'Oeste Rondônia 7067.025 22516
## 2 1 Norte Ariquemes Rondônia 4426.571 96833
## 3 1 Norte Cabixi Rondônia 1314.352 5067
## 4 1 Norte Cacoal Rondônia 3792.892 86416
## 5 1 Norte Cerejeiras Rondônia 2783.300 16088
## 6 1 Norte Colorado do Oeste Rondônia 1451.060 15213
## densidade geom
## 1 3.186065 MULTIPOLYGON (((-62.19465 -...
## 2 21.875397 MULTIPOLYGON (((-62.53648 -...
## 3 3.855132 MULTIPOLYGON (((-60.37119 -...
## 4 22.783670 MULTIPOLYGON (((-61.0008 -1...
## 5 5.780189 MULTIPOLYGON (((-61.49976 -...
## 6 10.484060 MULTIPOLYGON (((-60.50475 -...
Agora podemos criar um mapa colorindo as cidades de acordo com a sua densidade populacional:
ggplot() +
geom_sf(data = cidades, aes(fill = densidade))
Remover a cor dos limites municipais melhora um pouco a visualização:
ggplot() +
geom_sf(data = cidades, aes(fill = densidade), colour = NA)
Mas parece que nossa escala de cores não está funcionando bem. Há alguns pontos mais claros no mapa, como São Pualo, Rio de Janeiro e Belo Horizonte, mas não é poséivel distinguir bem as outras cidades.
O histograma da densidade populacional nos ajuda compreender isso:
ggplot(cidades, aes(x = densidade)) +
geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Uma forma de reduzir a desiguldade que vemos é aplicando uma transformação logarítmica, que além de reduzir a amplitude dos dados, os deixam simétricos:
ggplot(cidades, aes(x = densidade)) +
geom_histogram() +
scale_x_log10()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
É trivial aplicar esta transformação no mapa:
ggplot() +
geom_sf(data = cidades, aes(fill = densidade), colour = NA) +
scale_fill_gradient(trans = "log10")
Agora sim está mais fácil perceber a maior densidade populacional no litoral do Brasil, enquanto o interior é menos densamente populado.
A função read_state funciona de maneira análoga à função
read_municipality, exceto que só lê os mapas com divisões
estaduais:
uf <- read_state(year = 2020, showProgress = FALSE)
## Using year 2020
Como só possuímos os dados de densidade populacional para os municípios, precisamos agrupar estes dados por UF para termos a densidade populacional de cada Unidade Federativa do país.
densidade_uf <-
brasil |>
group_by(uf) |>
summarise(populacao_uf = sum(populacao),
area_uf = sum(area)) |>
mutate(densidade_uf = populacao_uf/area_uf)
Agora juntamos os mapas com os dados, como fizemos antes:
names(uf)
## [1] "code_state" "abbrev_state" "name_state" "code_region" "name_region"
## [6] "geom"
names(densidade_uf)
## [1] "uf" "populacao_uf" "area_uf" "densidade_uf"
uf <-
uf |>
rename(uf = name_state) |>
left_join(densidade_uf, by = "uf")
E aí é só plotar o resultado:
ggplot() +
geom_sf(data = uf, aes(fill = densidade_uf), colour = NA) +
scale_fill_gradient(trans = "log10")
Note que algumas UFs não possuem dados plotados a seu respeito. Isto
provavelmente se deve a diferentes grafias dos nomes dos estados nos
objetos uf e densidade_uf:
data.frame(sort(uf$uf), sort(densidade_uf$uf))
## sort.uf.uf. sort.densidade_uf.uf.
## 1 Acre Acre
## 2 Alagoas Alagoas
## 3 Amapá Amapá
## 4 Amazônas Amazonas
## 5 Bahia Bahia
## 6 Ceará Ceará
## 7 Distrito Federal Distrito Federal
## 8 Espírito Santo Espírito Santo
## 9 Goiás Goiás
## 10 Maranhão Maranhão
## 11 Mato Grosso Mato Grosso
## 12 Mato Grosso Do Sul Mato Grosso do Sul
## 13 Minas Gerais Minas Gerais
## 14 Pará Pará
## 15 Paraíba Paraíba
## 16 Paraná Paraná
## 17 Pernambuco Pernambuco
## 18 Piauí Piauí
## 19 Rio De Janeiro Rio de Janeiro
## 20 Rio Grande Do Norte Rio Grande do Norte
## 21 Rio Grande Do Sul Rio Grande do Sul
## 22 Rondônia Rondônia
## 23 Roraima Roraima
## 24 Santa Catarina Santa Catarina
## 25 São Paulo São Paulo
## 26 Sergipe Sergipe
## 27 Tocantins Tocantins
Era isso mesmo. Temos Amazônas com um acento incorreto e alguns estados com capitalizações não usuais em seus nomes. Isto precisa ser corrigido manualmente:
uf <-
read_state(year = 2020,
showProgress = FALSE
) |>
rename(uf = name_state) |>
mutate(uf = case_when(
uf == "Amazônas" ~ "Amazonas",
uf == "Mato Grosso Do Sul" ~ "Mato Grosso do Sul",
uf == "Rio De Janeiro" ~ "Rio de Janeiro",
uf == "Rio Grande Do Norte" ~ "Rio Grande do Norte",
uf == "Rio Grande Do Sul" ~ "Rio Grande do Sul",
.default = uf
))
## Using year 2020
Agora sim temos os estados com os mesmos nomes em cada objeto:
data.frame(sort(uf$uf), sort(densidade_uf$uf))
## sort.uf.uf. sort.densidade_uf.uf.
## 1 Acre Acre
## 2 Alagoas Alagoas
## 3 Amapá Amapá
## 4 Amazonas Amazonas
## 5 Bahia Bahia
## 6 Ceará Ceará
## 7 Distrito Federal Distrito Federal
## 8 Espírito Santo Espírito Santo
## 9 Goiás Goiás
## 10 Maranhão Maranhão
## 11 Mato Grosso Mato Grosso
## 12 Mato Grosso do Sul Mato Grosso do Sul
## 13 Minas Gerais Minas Gerais
## 14 Pará Pará
## 15 Paraíba Paraíba
## 16 Paraná Paraná
## 17 Pernambuco Pernambuco
## 18 Piauí Piauí
## 19 Rio de Janeiro Rio de Janeiro
## 20 Rio Grande do Norte Rio Grande do Norte
## 21 Rio Grande do Sul Rio Grande do Sul
## 22 Rondônia Rondônia
## 23 Roraima Roraima
## 24 Santa Catarina Santa Catarina
## 25 São Paulo São Paulo
## 26 Sergipe Sergipe
## 27 Tocantins Tocantins
Repetindo o código de antes, obtemos agora o resultado esperado:
uf_densidade <-
uf |>
left_join(densidade_uf, by = "uf")
ggplot() +
geom_sf(data = uf_densidade, aes(fill = densidade_uf), colour = NA) +
scale_fill_gradient(trans = "log10")
Não é necessário baixar os mapas de cada cidade brasileira quando
eestivermos interessados em apenas um estado da nação. O argumento
code_muni nos auxilia com isso, caso queiramos plotar o
mapa da densidade populacional do Rio Grande do Norte:
rn <- read_municipality(code_muni = "RN", year = 2020, showProgress = FALSE)
## Using year 2020
rn <-
rn |>
rename(codigo_ibge = code_muni) |>
left_join(brasil, by = "codigo_ibge")
ggplot() +
geom_sf(data = rn, aes(fill = densidade), colour = NA) +
scale_fill_gradient(trans = "log10")
Também é possível plotar dados apenas de uma cidade em particular.
Para Natal, a função read_neighborhood plota cada bairro da
cidade separadamente:
natal <- read_neighborhood(year = 2010, showProgress = FALSE)
## Using year 2010
natal <-
natal |>
filter(name_muni == "Natal")
ggplot() +
geom_sf(data = natal)
dados/pib_per_capita.csv para criar
um mapa do Brasil com as UFs coloridas de acordo com o PIB per
capita.pib_per_capita <-
read_csv(file = "dados/pib_per_capita.csv")
## Rows: 27 Columns: 2
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): uf
## dbl (1): pib_per_capita
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
uf_pib_per_capita <-
uf |>
left_join(pib_per_capita, by = "uf")
ggplot() +
geom_sf(data = uf_pib_per_capita, aes(fill = pib_per_capita)) +
scale_fill_gradient(trans = "log10")
# leitura dos mapas
uf_nordeste <- c("MA", "PI", "CE", "RN", "PB", "PE", "AL", "SE", "BA")
nordeste <- read_municipality(code_muni = "MA", year = 2020, showProgress = FALSE)
## Using year 2020
for(j in uf_nordeste[-1]){
nordeste <- bind_rows(nordeste,
read_municipality(code_muni = j, year = 2020))
}
## Using year 2020
## Using year 2020
## Using year 2020
## Using year 2020
## Using year 2020
## Using year 2020
## Using year 2020
## Using year 2020
# juntando mapas e dados
nordeste <-
nordeste |>
rename(codigo_ibge = code_muni) |>
left_join(brasil, by = "codigo_ibge")
ggplot() +
geom_sf(data = nordeste, aes(fill = densidade)) +
scale_fill_gradient(trans = "log10")
library(readxl)
unesco <- read_excel(path = "dados/whc-sites-2021.xls")
unesco_br_naturais <-
unesco |>
filter(states_name_en == "Brazil") |>
filter(category == "Natural")
ggplot() +
geom_sf(data = cidades) +
geom_point(data = unesco_br_naturais,
aes(x = longitude, y = latitude))